/**
 * 
 */
package org.shark.jdbcTemplateTool.binding;

import java.lang.annotation.Annotation;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.shark.jdbcTemplateTool.JdbcTemplateTool;
import org.shark.jdbcTemplateTool.dao.BasedaoUtil;
import org.shark.jdbcTemplateTool.dao.config.SqlCommand;
import org.shark.jdbcTemplateTool.exception.NoFoundSqlfileException;
import org.shark.jdbcTemplateTool.utils.SqlCommandUtil;
import org.shark.jdbcTemplateTool.utils.sql.SqlFileUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.repository.query.Param;

import com.google.common.collect.Maps;
import com.shark.app.common.utils.SpringUtil;

/**
 * @author lenovo
 * @description
 * @date 2016年8月19日
 */
public class DaoProxy<T> implements InvocationHandler {
			
	private Class<T> methodInterface;

	private static Logger log = LoggerFactory.getLogger(DaoProxy.class);

	public DaoProxy(Class<T> methodInterface) {
		this.methodInterface = methodInterface;
	}

	@Override
	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

		log.debug("=========================");
		log.debug("方法名:" + method.getName());

		JdbcTemplateTool jtt = SpringUtil.getBean(JdbcTemplateTool.class);
		SqlCommand sc = SqlCommandUtil.getSqlCommand(method);
		
		if (sc.isSuperMethod()) {
			log.debug("基类方法");
			switch (method.getName()) {
				case "get" :
					return BasedaoUtil.get(sc.getEntityClass(), args[0]);
				case "page":
					return BasedaoUtil.page(sc.getEntityClass(),
							(String)args[0], (Object[])args[1],
							Integer.parseInt((String)args[2]),
							Integer.parseInt((String)args[3]));
				case "update":
					return BasedaoUtil.update(args[0]);
				case "updateNotNull":
					return BasedaoUtil.updateNotNull(args[0]);
				case "save":
					return BasedaoUtil.save(args[0]);
				case "count":
					return BasedaoUtil.count((String)args[0], (Object[])args[1]);
				default:
					return null;
			}
		} else {
			log.debug("本接口方法");
			String sql = SqlFileUtil.newInstance.getSql(sc.getKey());

			// Sql 没有被缓存过
			if (StringUtils.isBlank(sql)) {
				throw new NoFoundSqlfileException(sc.getKey());
			}

			// 没有参数
			Map<String, Object> paramMap = Maps.newHashMap();
			int index = 0;
			Annotation[][] paramsAnnos = method.getParameterAnnotations();
			for (Annotation[] paramAnnos : paramsAnnos) {
				for (Annotation a : paramAnnos) {
					if (a instanceof Param) {
						paramMap.put(((Param) a).value(), args[index]);
					}
				}
				index++;
			}
			
			if (sc.isAdd() || sc.isDelete() || sc.isUpdate()) {
				return jtt.executeSql(sql, paramMap);
			} else {
				if (sc.isList()) {
					return jtt.list(sql, paramMap, sc.getReturnClass());
				} else {
					List<?> l = jtt.list(sql, paramMap, sc.getReturnClass());
					if (l.size() > 0) {
						return l.get(0);
					} else {
						return null;
					}
				}
			}
		}
	}	
}
